﻿using System;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Ria;
using System.Windows.Ria.ApplicationServices;
using SoftSource.Reactive;
using SoftSource.Ria;

namespace SoftSource.Controls
{
    public class SharedController
    {
        #region Auto Grid Editor View
        public static UIElement CreateAutoGridEditorView(IAutoGridEditorViewModelService vm)
        {
            FrameworkElement view = new AutoGridEditorView();

            view.DataContext = vm;

            return view;
        }
        #endregion Auto Grid Editor View

        #region Auto Grid Editor View Model
        public static IAutoGridEditorViewModelService CreateAutoGridEditorViewModel<T>(EntityWrapper<T> wrapper, string sortName) where T : Entity, new()
        {
            return SharedController.CreateAutoGridEditorViewModel(wrapper, sortName, true, false, null);
        }
        public static IAutoGridEditorViewModelService CreateAutoGridEditorViewModel<T>(
            EntityWrapper<T> wrapper,
            string sortName,
            bool canAdd,
            bool canDelete,
            Action<DataGridAutoGeneratingColumnEventArgs> onAutoGenerating) where T : Entity, new()
        {
            IAutoGridEditorViewModelService vm = new AutoGridEditorViewModel();

            vm.OnAutoGenerating = onAutoGenerating;
            vm.Collection = wrapper.Entities;
            vm.Save = arg => wrapper.Save.ToUnit();
            vm.SortDescriptions.Add(new SortDescription(sortName, ListSortDirection.Ascending));

            Func<object> addNew = () => wrapper.AddNew();
            vm.Add = canAdd ? addNew : null;

            if (canDelete)
            {
                vm.Delete = (arg, callback) =>
                {
                    if (arg != null && arg is T)
                    {
                        T val = (T)arg;
                        wrapper.Remove(val);
                        wrapper.Save.Subscribe(unit => callback());
                    }
                };
            }
            else
            {
                vm.Delete = null;
            }

            return vm;
        }
        #endregion Auto Grid Editor View Model

        #region Login View
        public static UIElement CreateLoginView(
            AuthenticationService authenticationService,
            Func<string, string> modifyUsername,
            Action completed)
        {
            FrameworkElement view = new LoginView();

            view.DataContext = SharedController.CreateLoginViewModel(authenticationService, modifyUsername, completed);

            return view;
        }
        #endregion Login View

        #region Login View Model
        public static ILoginViewModelService CreateLoginViewModel(
            AuthenticationService authenticationService,
            Func<string, string> modifyUsername,
            Action completed)
        {
            ILoginViewModelService vm = new LoginViewModel();

            vm.Login = Observable.CreateWithDisposable<bool>(observer =>
                {
                    return authenticationService.WhenLogin(new LoginParameters(modifyUsername(vm.Username), vm.Password, vm.RememberMe, null))
                        .Select(lo => lo.LoginSuccess)
                        .Catch(Observable.Return(false))
                        .Subscribe(observer);
                }).Do(success =>
                    {
                        if (success)
                            completed();
                    });
            vm.Cancel = completed;

            return vm;
        }
        #endregion Login View Model
    }
}
